// Example of a grammar for parsing C sources,
//
/** \mainpage G-mini Documentation
*
*\author Jad Makhlouta
*\author Layale Constantine
* \date 29-01-2011
*\image html BabyGnu.png
*
*Project that parses and checks models for a language called mini that contains a subset of C++
*/
#include 	<visitor.h>
#include    <gminiLexer.h>
#include    <gminiParser.h>
#include	<cstring>
#include 	"translate.h"
#include	"visitor2.h"
#include	"check.h"

/**
  \brief The start point of our program that performs the parsing and translation and model check

  \note Antlr aspects adapted from Jim Idle (jimi cut-this at idle ws) excluding the lengthy comments which were removed for convenience in a grammar for parsing C sources.
 */
int ANTLR3_CDECL
main	(int argc, char *argv[])
{

    pANTLR3_UINT8	fName;
    pANTLR3_INPUT_STREAM    input;
    pgminiLexer		lxr;
    pANTLR3_COMMON_TOKEN_STREAM	    tstream;
    pgminiParser	psr;
    if (argc < 2 || argv[1] == NULL)
    {
		fName	=(pANTLR3_UINT8)"./input";
    }
    else
    {
		fName	= (pANTLR3_UINT8)argv[1];
    }
    input	= antlr3AsciiFileStreamNew(fName);

    if ( input == NULL)
    {
	    fprintf(stderr, "Failed to open file %s\n", (char *)fName);
		exit(1);
	}

    lxr	    = gminiLexerNew(input);	   

    if ( lxr == NULL )
    {
	    fprintf(stderr, "Unable to create the lexer due to malloc() failure1\n");
	    exit(1);
    }
	tstream = antlr3CommonTokenStreamSourceNew(ANTLR3_SIZE_HINT, TOKENSOURCE(lxr));

    if (tstream == NULL)
    {
	fprintf(stderr, "Out of memory trying to allocate token stream\n");
	exit(1);
    }
    psr	    = gminiParserNew(tstream); 

    if (psr == NULL)
    {
		fprintf(stderr, "Out of memory trying to allocate parser\n");
		exit(ANTLR3_ERR_NOMEM);
    }

    //Here are our main code changes to that of Jim Idle
    Node * startingNode=psr->statements(psr);
	parsingGraph.setRoot(startingNode);
	if (argc==2)
	{
		DisplayVisitor v;
		Traversal t(parsingGraph,v);
		t();
	}
	if (argc>2)
	{
		NewGraph * g=translate(&parsingGraph);
		if (strcmp(argv[2],"translate-twice")==0)
		{
			GminiGraph * gm = translate(*g);
			DisplayVisitor vm;
			Traversal t3(*gm, vm);
			t3();
		}
		else if (strcmp(argv[2],"translate-once")==0)
		{
			DisplayVisitor2 v2;
			NewGraphDFTraversal t2(v2,1);
			t2(*g);
			g->resetColor();
		}
		else
			checkModel(g, argv[2]);
		delete g;
	}
	parsingGraph.deleteSubTree(startingNode);
	//Here is all what we added
	
    
    psr	    ->free  (psr);	    psr = NULL;
    tstream ->free  (tstream);	    tstream = NULL;
    lxr	    ->free  (lxr);	    lxr = NULL;
    input   ->close (input);	    input = NULL;

    return 0;
}

